<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>豆瓣活动地图</title>
    <link href="eventsmap.css" rel="stylesheet" type="text/css" />
</head>
<body onload="initialize()">

<div id="map_canvas"></div>

<script id="infotmpl" type="text/x-jquery-tmpl">
<div>
<h2><a href="${link.alternate}" target="_blank">${title}</a></h2>
<div class="poster">
    <img src="${link.image}" title="${title}">
</div>
<div class="info">
    <span class="pl">开始时间:</span>${dateFormat(when.startTime, "yyyy年mm月dd日 DDD HH:MM")}<br/>
    <span class="pl">结束时间:</span>${dateFormat(when.endTime, "yyyy年mm月dd日 DDD HH:MM")}<br/>
    <span class="pl">地点:</span>${where}<br/>
    {{if author}}
    <span class="pl">发起人:</span><a href="${author.link.alternate}" target='_blank'>${author.name}</a><br/>
    {{/if}}
    ${attribute.wishers}人感兴趣，${attribute.participants}人参加
    <a href="http://www.douban.com/event/album/${attribute.album}/" target='_blank'>活动照片</a>
</div><br/>
<div class="desc">
    <pre>${summary}</pre>
</div>
</div>
</script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=places&sensor=true&language=zh-CN&region=CN"></script>
<script type="text/javascript" src="/assets/lib/jquery/jquery.js"></script>
<script type="text/javascript" src="/assets/lib/jquery/jquery.tmpl.js"></script>
<script type="text/javascript" src="/assets/lib/jquery/jquery.urldecoder.js"></script>
<script type="text/javascript" src="/assets/js/options.js"></script>
<script type="text/javascript" src="/assets/js/utils.js" charset="UTF-8"></script>
<script type="text/javascript" src="/assets/lib/oauth/sha1.js"></script>
<script type="text/javascript" src="/assets/lib/oauth/oauth.js"></script>
<script type="text/javascript" src="/assets/lib/douban/douban.js"></script>
<script type="text/javascript" src="/assets/lib/douban/api-parser.js"></script>
<script type="text/javascript" src="/assets/lib/gmap/markerclusterer.json"></script>
<script type="text/javascript" src="/assets/lib/gmap/markerclusterer.js"></script>
<script type="text/javascript">
var map;
var geocoder;
var places;
var infowin;
var bounds;
var markers;

function initialize() {
    listen_events_stream();

    init_map_services();
    move_to_current_position();

    process_events_query();
}

function init_map_services() {
    var opts = {
        zoom: 12,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), opts);
    geocoder = new google.maps.Geocoder();
    places = new google.maps.places.PlacesService(map);
    bounds = new google.maps.LatLngBounds();
    markers = new MarkerClusterer(map, [], {
        maxZoom: 14,
        imagePath: '/assets/img/map/m'
    });
}

function move_to_current_position() {
    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            var initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);

            console.log("set center to " + initialLocation + " base on the HTML5 geolocation");

            map.setCenter(initialLocation);
        }, function() {
            handleNoGeolocation();
        });
    } else {
        handleNoGeolocation();
    }
}

function query_location(location, callback) {
    chrome.extension.sendRequest({
        action: 'location',
        location: location
    }, function (response) {
        callback(response.geometry, response.status);
    });
}

function query_place(location, place, callback) {
    chrome.extension.sendRequest({
        action: 'place',
        location: location,
        place: place
    }, function (response) {
        callback(response.geometry, response.status);
    });
}

function handleNoGeolocation() {
    var api = DOUBAN.create_api();

    api.getCurrentUser(function (user) {
        query_location(user.location, function (geometry) {
            console.log("set center to " + geometry.location + " base on the user location");

            map.setCenter(geometry.location);
        });
    }, function (error, status, xhr) {
        query_location('北京', function (geometry) {
            console.log("set center to " + geometry.location + " base on the fixed location");

            map.setCenter(geometry.location);
        });
    });
}

function show_event(event) {
    if (event.geometry) {
        drop_marker(event);
    } else {
        query_place(event.location, event.where, function (geometry) {
            if (geometry) {
                console.log(geometry);

                event.geometry = {
                    location : {
                        lat: geometry.location['Ja'],
                        lng: geometry.location['Ka']
                    }
                }

                drop_marker(event);
            }
        });
    }
}

function drop_marker(event) {
    var pos = new google.maps.LatLng(event.geometry.location.lat, event.geometry.location.lng);

    console.log("drop mark at " + pos + " for " + event.title);

    bounds.extend(pos);

    var marker = new google.maps.Marker({
        position: pos,
        //map: map,
        title: event.title,
        animation: google.maps.Animation.DROP,
        icon: chrome.extension.getURL('/assets/img/map/' + event.category.split('.')[1] + '.png')
    });

    markers.addMarker(marker);

    google.maps.event.addListener(marker, 'click', function () {
        map.setCenter(pos);

        if (infowin) infowin.close();

        infowin = new google.maps.InfoWindow({
            content: $('#infotmpl').tmpl(event).html()
        });
        infowin.open(map, marker);
    });
}

function listen_events_stream() {
    chrome.extension.onConnect.addListener(function(port) {
        if (port.name == 'events') {
            port.onMessage.addListener(function(event) {
                show_event(event);
            });
        }
    });
}

function query_events_query(request) {
    console.log(request);
    console.log("query events " + request.url + "?" + $.param(request.params));

    $.getJSON(request.url, request.params, function (json) {
        var events = DOUBAN.parseEvents(json);

        console.log(json);
        console.log(events);

        $.each(events.entries, function (idx, event) {
            request.totalItemCount += 1;

            if (request.items[event.id]) {
                console.log("skip the duplicate event #" + event.id);
                
                return true;
            }
            
            if (request.params.when) {
                if ((request.params.when.startTime && event.when.endTime < request.params.when.startTime) ||
                    (request.params.when.endTime && event.when.startTime >= request.params.when.endTime)) {
                    console.log("skip the event #" + event.id + " by time [" + event.when.startTime + ", " + event.when.endTime + "]");

                    return true;
                }
            }

            var category = event.category.split('.')[1];

            if (request.params.type &&
                request.params.type.indexOf(category) < 0) {
                console.log("skip the event #" + event.id + " by type " + category);

                return true;
            }

            request.items[event.id] = event;
            request.validItemCount += 1;

            show_event(event);
        });

        if (request.totalItemCount < events.totalResults &&
            request.validItemCount < request.limit) {
            request.params['start-index'] = events.startIndex + events.itemPerPage;
            request.params['max-results'] = events.itemPerPage;

            query_events_query(request);
        } else {
            map.fitBounds(bounds);

            console.log("found " + request.validItemCount + "/" + request.totalItemCount +  " events");
        }
    });
}

function process_events_query() {
    var request = create_request();

    if (request) {
        read_option('douban_api_key', function (k, v) {
            request.params.apikey = v;

            query_events_query(request);
        });
    }
}

function create_request() {
    var url = $.url.parse(window.location.href);

    var request = {
        url: null,
        params: {
            alt: 'json'
        },
        items: {},
        totalItemCount: 0,
        validItemCount: 0
    };

    if (url.params.uid) {
        request.url = 'http://api.douban.com/people/' + url.params.uid + '/events';

        if (url.params.action) {
            request.url += '/' + url.params.action;
        }
    } else if (url.params.location) {
        if (url.params.q) {
            request.url = 'http://api.douban.com/event';

            request.params.location = url.params.location;
            request.params.q = url.params.q;
        } else {
            request.url = 'http://api.douban.com/event/location/' + url.params.location;

            if (url.params.type) {
                request.params.type = url.params.type;
            }
        }
    } else {
        return null;
    }

    if (url.params.type) {
        request.params.type = url.params.type.split(',');
    }
    if (url.params['start-index']) {
        request.params['start-index'] = url.params['start-index'];
    }
    if (url.params['max-results']) {
        request.params['max-results'] = url.params['max-results'];
    }

    request.limit = url.params.limit || 100;

    if (url.params['start-time'] || url.params['end-time']) {
        request.params.when = {
            startTime: url.params['start-time'] ? new Date(url.params['start-time']) : null,
            endTime: url.params['end-time'] ? new Date(url.params['end-time']) : null
        }
    } else if (url.params.time) {
        var now = new Date();

        now = new Date(now.getFullYear()+'-'+(now.getMonth()+1)+'-'+now.getDate());

        var HOUR = 60*60*1000;
        var DAY = 24*HOUR;

        if (url.params.time == 'today') {
            startTime = now;
            endTime = new Date(now.valueOf() + DAY);
        } else if (url.params.time == 'week') {
            startTime = now;
            endTime = new Date(now.valueOf() + 7*DAY);
        } else if (url.params.time == 'weekend') {
            var startDay = 5 - now.getDay();
            var endDay = 7 - now.getDay();

            startTime = startDay < 0 ? now : new Date(now.valueOf() + startDay*DAY + 18*HOUR);
            endTime = new Date(now.valueOf() + (endDay+1)*DAY);
        } else {
            date = new Date(url.params.time);
            date = new Date(now.getFullYear()+'-'+now.getMonth()+'-'+now.getDate());

            startTime = date;
            endTime = new Date(date.valueOf() + DAY);
        }

        console.log("filter events from " + startTime + " to " + endTime);

        request.params.when = {
            startTime: startTime,
            endTime: endTime
        }
    } 

    return request;
}
</script>
</body>
</html> 